package com.example.myapplication;

import android.app.AppOpsManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserManager;
import android.util.Log;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 应用使用统计服务
 */
public class AppUsageService {
    private static final String TAG = "AppUsageService";
    private Context context;
    private UsageStatsManager usageStatsManager;
    private PackageManager packageManager;

    public AppUsageService(Context context) {
        this.context = context;
        this.usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        this.packageManager = context.getPackageManager();
    }

    /**
     * 检查是否有使用统计权限
     * 参考官方文档: https://developer.android.com/reference/android/app/usage/UsageStatsManager
     * 
     * 重要说明：
     * 1. PACKAGE_USAGE_STATS 是特殊权限，需要通过 Settings.ACTION_USAGE_ACCESS_SETTINGS 跳转到系统设置页面授权
     * 2. 从 Android R (API 30) 开始，如果设备未解锁，queryAndAggregateUsageStats 会返回 null
     * 3. 即使有权限，如果没有使用数据，也可能返回空 Map，不能仅凭返回值判断权限
     */
    public boolean hasUsageStatsPermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            Log.d(TAG, "Android版本过低，不支持使用统计 (需要 API 21+)");
            return false;
        }
        
        if (usageStatsManager == null) {
            Log.w(TAG, "UsageStatsManager为null，无法获取使用统计");
            return false;
        }
        
        // Android R+ 检查设备是否解锁
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            try {
                UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
                if (userManager != null && !userManager.isUserUnlocked()) {
                    Log.w(TAG, "设备未解锁，无法获取使用统计（Android R+ 要求）");
                    return false;
                }
            } catch (Exception e) {
                Log.w(TAG, "检查设备解锁状态失败: " + e.getMessage());
                // 继续检查权限，不直接返回false
            }
        }
        
        // 主要方法: 使用AppOpsManager检测权限（最可靠的方法）
        try {
            AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            if (appOps == null) {
                Log.w(TAG, "AppOpsManager为null");
                return false;
            }
            
            int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, 
                    android.os.Process.myUid(), context.getPackageName());
            
            Log.d(TAG, "AppOpsManager检查结果 - mode: " + mode + 
                    " (MODE_ALLOWED=" + AppOpsManager.MODE_ALLOWED + 
                    ", MODE_DEFAULT=" + AppOpsManager.MODE_DEFAULT + 
                    ", MODE_IGNORED=" + AppOpsManager.MODE_IGNORED + ")");
            
            // 对于特殊权限 PACKAGE_USAGE_STATS，主要依赖 AppOpsManager 的检查
            // MODE_ALLOWED 表示已授权
            // MODE_DEFAULT 表示未授权或未设置
            // MODE_IGNORED 表示被拒绝
            boolean granted = (mode == AppOpsManager.MODE_ALLOWED);
            
            if (granted) {
                // 双重验证：尝试实际查询数据确认权限有效
                // 注意：即使有权限，如果没有数据也可能返回空 Map，不能仅凭此判断
                try {
                    long currentTime = System.currentTimeMillis();
                    long startTime = currentTime - (7 * 24 * 60 * 60 * 1000); // 7天前（扩大时间范围以获取更多数据）
                    
                    Map<String, UsageStats> usageStatsMap = usageStatsManager.queryAndAggregateUsageStats(
                            startTime, currentTime);
                    
                    // 如果返回 null，可能是设备未解锁（Android R+）或没有权限
                    if (usageStatsMap == null) {
                        Log.w(TAG, "queryAndAggregateUsageStats返回null - 可能是设备未解锁或权限不足");
                        // 对于 Android R+，null 可能表示设备未解锁，但我们已经有权限
                        // 对于较旧版本，null 通常表示没有权限
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                            // Android R+ 上，null 可能是设备未解锁，但我们检查权限时已经检查过
                            // 如果 AppOpsManager 显示有权限，我们相信它
                            Log.d(TAG, "Android R+ 上返回null，但AppOpsManager显示有权限，认为权限有效");
                            return true;
                        } else {
                            // 较旧版本上，null 通常表示没有权限
                            Log.w(TAG, "Android R以下版本返回null，认为权限无效");
                            return false;
                        }
                    }
                    
                    // 有权限且能查询到数据（即使为空Map）
                    Log.d(TAG, "权限验证成功 - 数据量: " + usageStatsMap.size());
                    return true;
                    
                } catch (SecurityException e) {
                    Log.w(TAG, "AppOpsManager显示有权限，但实际查询失败（SecurityException）: " + e.getMessage());
                    return false;
                } catch (Exception e) {
                    Log.e(TAG, "实际查询验证时出错", e);
                    // 如果查询出错但不是 SecurityException，可能是其他原因
                    // 但我们仍然认为权限有效（因为 AppOpsManager 显示有权限）
                    return true;
                }
            } else {
                Log.d(TAG, "AppOpsManager显示未授权 - mode: " + mode);
                return false;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "AppOpsManager权限检测失败", e);
        }
        
        // 备用方法: 尝试实际查询来检测权限（仅当 AppOpsManager 检查失败时使用）
        Log.d(TAG, "使用备用方法检测权限");
        try {
            long currentTime = System.currentTimeMillis();
            long startTime = currentTime - (24 * 60 * 60 * 1000); // 24小时前
            
            // 尝试查询使用统计数据
            Map<String, UsageStats> usageStatsMap = usageStatsManager.queryAndAggregateUsageStats(
                    startTime, currentTime);
            
            // 如果能成功返回（不为null），说明有权限（即使为空Map）
            boolean hasPermission = (usageStatsMap != null);
            Log.d(TAG, "备用方法-权限检测结果: " + hasPermission + 
                    ", 数据量: " + (usageStatsMap != null ? usageStatsMap.size() : 0));
            
            return hasPermission;
            
        } catch (SecurityException e) {
            Log.d(TAG, "备用方法-没有使用统计权限 (SecurityException): " + e.getMessage());
            return false;
        } catch (Exception e) {
            Log.e(TAG, "备用方法-检测使用统计权限时出错: " + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 获取今日应用使用统计
     */
    public List<AppUsageInfo> getTodayAppUsage() {
        return getAppUsage(Calendar.DAY_OF_MONTH, 1);
    }

    /**
     * 获取近7天应用使用统计
     */
    public List<AppUsageInfo> getWeeklyAppUsage() {
        return getAppUsage(Calendar.DAY_OF_MONTH, 7);
    }
    
    /**
     * 获取指定日期范围的应用使用统计
     */
    public List<AppUsageInfo> getAppUsageByDateRange(long startTime, long endTime) {
        return getAppUsageByTimeRange(startTime, endTime);
    }
    
    /**
     * 获取指定天数的应用使用统计
     */
    public List<AppUsageInfo> getAppUsageByDays(int days) {
        return getAppUsage(Calendar.DAY_OF_MONTH, days);
    }
    
    /**
     * 使用 INTERVAL_DAILY 获取每日应用使用统计
     * 参考: UsageStatsManager.INTERVAL_DAILY
     */
    public List<AppUsageInfo> getAppUsageByIntervalDaily() {
        return getAppUsageByInterval(UsageStatsManager.INTERVAL_DAILY);
    }
    
    /**
     * 使用 INTERVAL_WEEKLY 获取每周应用使用统计
     * 参考: UsageStatsManager.INTERVAL_WEEKLY
     */
    public List<AppUsageInfo> getAppUsageByIntervalWeekly() {
        return getAppUsageByInterval(UsageStatsManager.INTERVAL_WEEKLY);
    }
    
    /**
     * 使用 INTERVAL_MONTHLY 获取每月应用使用统计
     * 参考: UsageStatsManager.INTERVAL_MONTHLY
     */
    public List<AppUsageInfo> getAppUsageByIntervalMonthly() {
        return getAppUsageByInterval(UsageStatsManager.INTERVAL_MONTHLY);
    }
    
    /**
     * 使用 INTERVAL_YEARLY 获取每年应用使用统计
     * 参考: UsageStatsManager.INTERVAL_YEARLY
     */
    public List<AppUsageInfo> getAppUsageByIntervalYearly() {
        return getAppUsageByInterval(UsageStatsManager.INTERVAL_YEARLY);
    }
    
    /**
     * 使用 INTERVAL_BEST 获取最佳间隔的应用使用统计
     * 参考: UsageStatsManager.INTERVAL_BEST
     */
    public List<AppUsageInfo> getAppUsageByIntervalBest() {
        return getAppUsageByInterval(UsageStatsManager.INTERVAL_BEST);
    }
    
    /**
     * 使用指定间隔类型获取应用使用统计
     * @param intervalType 间隔类型 (INTERVAL_DAILY, INTERVAL_WEEKLY, INTERVAL_MONTHLY, INTERVAL_YEARLY, INTERVAL_BEST)
     */
    public List<AppUsageInfo> getAppUsageByInterval(int intervalType) {
        List<AppUsageInfo> appUsageList = new ArrayList<>();
        
        if (!hasUsageStatsPermission()) {
            Log.e(TAG, "没有使用统计权限");
            return appUsageList;
        }

        try {
            Calendar calendar = Calendar.getInstance();
            long endTime = calendar.getTimeInMillis();
            
            // 根据间隔类型计算开始时间
            long startTime = calculateStartTimeByInterval(intervalType, endTime);
            
            Log.d(TAG, "查询间隔类型: " + getIntervalTypeName(intervalType) + 
                    ", 开始时间: " + new java.util.Date(startTime) + 
                    ", 结束时间: " + new java.util.Date(endTime));

            // 使用 queryUsageStats 方法获取统计数据
            List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(
                    intervalType, startTime, endTime);
            
            if (usageStatsList == null || usageStatsList.isEmpty()) {
                Log.d(TAG, "未获取到使用统计数据");
                return appUsageList;
            }
            
            Log.d(TAG, "获取到 " + usageStatsList.size() + " 个应用的使用统计");

            // 获取所有已安装的应用
            List<ApplicationInfo> installedApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
            
            // 创建应用包名到 UsageStats 的映射
            Map<String, UsageStats> usageMap = new HashMap<>();
            for (UsageStats stats : usageStatsList) {
                usageMap.put(stats.getPackageName(), stats);
            }

            // 遍历所有已安装的应用
            for (ApplicationInfo appInfo : installedApps) {
                String packageName = appInfo.packageName;
                
                // 跳过系统应用（可选）
                if (isSystemApp(appInfo)) {
                    continue;
                }

                // 获取使用统计数据
                UsageStats usageStats = usageMap.get(packageName);
                if (usageStats == null) {
                    // 如果没有使用数据，跳过这个应用
                    continue;
                }

                // 创建应用使用信息
                AppUsageInfo appUsageInfo = createAppUsageInfo(packageName, usageStats, appInfo);
                if (appUsageInfo != null) {
                    appUsageList.add(appUsageInfo);
                }
            }

            // 按使用时间排序
            Collections.sort(appUsageList, new Comparator<AppUsageInfo>() {
                @Override
                public int compare(AppUsageInfo o1, AppUsageInfo o2) {
                    int timeCompare = Long.compare(o2.getTotalTimeInForeground(), o1.getTotalTimeInForeground());
                    if (timeCompare != 0) {
                        return timeCompare;
                    }
                    return o1.getAppName().compareTo(o2.getAppName());
                }
            });

            Log.d(TAG, "处理完成，返回 " + appUsageList.size() + " 个应用的使用统计");
            return appUsageList;

        } catch (Exception e) {
            Log.e(TAG, "获取应用使用统计失败", e);
            return appUsageList;
        }
    }
    
    /**
     * 根据间隔类型计算开始时间
     */
    private long calculateStartTimeByInterval(int intervalType, long endTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(endTime);
        
        switch (intervalType) {
            case UsageStatsManager.INTERVAL_DAILY:
                // 今天
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                return calendar.getTimeInMillis();
                
            case UsageStatsManager.INTERVAL_WEEKLY:
                // 本周
                calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                return calendar.getTimeInMillis();
                
            case UsageStatsManager.INTERVAL_MONTHLY:
                // 本月
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                return calendar.getTimeInMillis();
                
            case UsageStatsManager.INTERVAL_YEARLY:
                // 今年
                calendar.set(Calendar.DAY_OF_YEAR, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                return calendar.getTimeInMillis();
                
            case UsageStatsManager.INTERVAL_BEST:
                // 最佳间隔，系统会自动选择最合适的时间范围
                // 通常返回过去一段时间的数据
                calendar.add(Calendar.DAY_OF_MONTH, -30); // 默认30天
                return calendar.getTimeInMillis();
                
            default:
                // 默认返回今天
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                return calendar.getTimeInMillis();
        }
    }
    
    /**
     * 获取间隔类型名称（用于日志）
     */
    private String getIntervalTypeName(int intervalType) {
        switch (intervalType) {
            case UsageStatsManager.INTERVAL_DAILY:
                return "INTERVAL_DAILY";
            case UsageStatsManager.INTERVAL_WEEKLY:
                return "INTERVAL_WEEKLY";
            case UsageStatsManager.INTERVAL_MONTHLY:
                return "INTERVAL_MONTHLY";
            case UsageStatsManager.INTERVAL_YEARLY:
                return "INTERVAL_YEARLY";
            case UsageStatsManager.INTERVAL_BEST:
                return "INTERVAL_BEST";
            default:
                return "UNKNOWN(" + intervalType + ")";
        }
    }
    
    /**
     * 获取指定间隔类型的应用使用统计数据（用于上报服务器）
     * @param intervalType 间隔类型
     * @return 应用使用统计数据列表，格式为 DeviceDataModel.AppUsageData
     */
    public List<DeviceDataModel.AppUsageData> getAppUsageDataForUpload(int intervalType) {
        List<DeviceDataModel.AppUsageData> appUsageDataList = new ArrayList<>();
        
        List<AppUsageInfo> appUsageList = getAppUsageByInterval(intervalType);
        
        for (AppUsageInfo appUsageInfo : appUsageList) {
            DeviceDataModel.AppUsageData appUsageData = new DeviceDataModel.AppUsageData();
            appUsageData.setPackageName(appUsageInfo.getPackageName());
            appUsageData.setAppName(appUsageInfo.getAppName());
            appUsageData.setTotalTime(appUsageInfo.getTotalTimeInForeground());
            appUsageData.setLastUsedTime(appUsageInfo.getLastTimeUsed());
            appUsageDataList.add(appUsageData);
        }
        
        Log.d(TAG, "准备上报 " + appUsageDataList.size() + " 个应用的使用统计数据");
        return appUsageDataList;
    }

    /**
     * 获取指定时间范围内的应用使用统计（直接指定时间范围）
     */
    private List<AppUsageInfo> getAppUsageByTimeRange(long startTime, long endTime) {
        List<AppUsageInfo> appUsageList = new ArrayList<>();
        
        if (!hasUsageStatsPermission()) {
            Log.e(TAG, "没有使用统计权限");
            return appUsageList;
        }

        try {
            // 获取所有已安装的应用
            List<ApplicationInfo> installedApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
            Log.d(TAG, "找到 " + installedApps.size() + " 个已安装应用");

            // 获取使用统计数据
            Map<String, UsageStats> usageStatsMap = usageStatsManager.queryAndAggregateUsageStats(
                    startTime, endTime);

            // 创建应用使用信息映射
            Map<String, UsageStats> usageMap = usageStatsMap != null ? usageStatsMap : new HashMap<>();

            // 遍历所有已安装的应用
            for (ApplicationInfo appInfo : installedApps) {
                String packageName = appInfo.packageName;
                
                // 跳过系统应用（可选）
                if (isSystemApp(appInfo)) {
                    continue;
                }

                // 获取使用统计数据
                UsageStats usageStats = usageMap.get(packageName);
                if (usageStats == null) {
                    // 如果没有使用数据，跳过这个应用（不显示没有使用时间的应用）
                    continue;
                }

                // 创建应用使用信息（包括没有使用时间的应用）
                AppUsageInfo appUsageInfo = createAppUsageInfo(packageName, usageStats, appInfo);
                if (appUsageInfo != null) {
                    appUsageList.add(appUsageInfo);
                }
            }

            // 按使用时间排序（有使用时间的排在前面）
            Collections.sort(appUsageList, new Comparator<AppUsageInfo>() {
                @Override
                public int compare(AppUsageInfo o1, AppUsageInfo o2) {
                    // 先按使用时间排序
                    int timeCompare = Long.compare(o2.getTotalTimeInForeground(), o1.getTotalTimeInForeground());
                    if (timeCompare != 0) {
                        return timeCompare;
                    }
                    // 如果使用时间相同，按应用名称排序
                    return o1.getAppName().compareTo(o2.getAppName());
                }
            });

            Log.d(TAG, "获取到 " + appUsageList.size() + " 个应用的使用统计");
            return appUsageList;

        } catch (Exception e) {
            Log.e(TAG, "获取应用使用统计失败", e);
            return appUsageList;
        }
    }

    /**
     * 获取指定时间范围内的应用使用统计
     */
    private List<AppUsageInfo> getAppUsage(int timeUnit, int amount) {
        List<AppUsageInfo> appUsageList = new ArrayList<>();
        
        if (!hasUsageStatsPermission()) {
            Log.e(TAG, "没有使用统计权限");
            return appUsageList;
        }

        try {
            Calendar calendar = Calendar.getInstance();
            long endTime = calendar.getTimeInMillis();
            
            calendar.add(timeUnit, -amount);
            long startTime = calendar.getTimeInMillis();

            // 获取所有已安装的应用
            List<ApplicationInfo> installedApps = packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
            Log.d(TAG, "找到 " + installedApps.size() + " 个已安装应用");

            // 获取使用统计数据
            Map<String, UsageStats> usageStatsMap = usageStatsManager.queryAndAggregateUsageStats(
                    startTime, endTime);

            // 创建应用使用信息映射
            Map<String, UsageStats> usageMap = usageStatsMap != null ? usageStatsMap : new HashMap<>();

            // 遍历所有已安装的应用
            for (ApplicationInfo appInfo : installedApps) {
                String packageName = appInfo.packageName;
                
                // 跳过系统应用（可选）
                if (isSystemApp(appInfo)) {
                    continue;
                }

                // 获取使用统计数据
                UsageStats usageStats = usageMap.get(packageName);
                if (usageStats == null) {
                    // 如果没有使用数据，跳过这个应用（不显示没有使用时间的应用）
                    continue;
                }

                // 创建应用使用信息（包括没有使用时间的应用）
                AppUsageInfo appUsageInfo = createAppUsageInfo(packageName, usageStats, appInfo);
                if (appUsageInfo != null) {
                    appUsageList.add(appUsageInfo);
                }
            }

            // 按使用时间排序（有使用时间的排在前面）
            Collections.sort(appUsageList, new Comparator<AppUsageInfo>() {
                @Override
                public int compare(AppUsageInfo o1, AppUsageInfo o2) {
                    // 先按使用时间排序
                    int timeCompare = Long.compare(o2.getTotalTimeInForeground(), o1.getTotalTimeInForeground());
                    if (timeCompare != 0) {
                        return timeCompare;
                    }
                    // 如果使用时间相同，按应用名称排序
                    return o1.getAppName().compareTo(o2.getAppName());
                }
            });

            Log.d(TAG, "获取到 " + appUsageList.size() + " 个应用的使用统计");
            return appUsageList;

        } catch (Exception e) {
            Log.e(TAG, "获取应用使用统计失败", e);
            return appUsageList;
        }
    }

    /**
     * 创建应用使用信息对象
     */
    private AppUsageInfo createAppUsageInfo(String packageName, UsageStats usageStats, ApplicationInfo appInfo) {
        try {
            String appName = packageManager.getApplicationLabel(appInfo).toString();
            
            AppUsageInfo appUsageInfo = new AppUsageInfo();
            appUsageInfo.setPackageName(packageName);
            appUsageInfo.setAppName(appName);
            appUsageInfo.setTotalTimeInForeground(usageStats.getTotalTimeInForeground());
            appUsageInfo.setLastTimeUsed(usageStats.getLastTimeUsed());
            // 启动次数暂时设置为0，因为getLaunchCount()方法在当前API级别不可用
            appUsageInfo.setLaunchCount(0);
            
            // 设置应用信息（用于获取图标）
            appUsageInfo.setApplicationInfo(appInfo);
            
            return appUsageInfo;
            
        } catch (Exception e) {
            Log.w(TAG, "创建应用使用信息失败: " + packageName, e);
            return null;
        }
    }

    /**
     * 判断是否为系统应用
     */
    private boolean isSystemApp(ApplicationInfo appInfo) {
        return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
    }


    /**
     * 获取总使用时间
     */
    public long getTotalUsageTime(List<AppUsageInfo> appUsageList) {
        long totalTime = 0;
        for (AppUsageInfo appUsageInfo : appUsageList) {
            totalTime += appUsageInfo.getTotalTimeInForeground();
        }
        return totalTime;
    }

    /**
     * 按类别分组应用
     */
    public Map<String, List<AppUsageInfo>> groupAppsByCategory(List<AppUsageInfo> appUsageList) {
        // 这里可以实现按类别分组的逻辑
        // 为了简化，暂时返回null
        return null;
    }
}